<?php
namespace Curl;
/**
 * Curl操作类
 * 
 * @author freephp
 */
class SimpleCurl
{
    // curl对象
    public $curl;

    // 访问的URL地址
    private  $url = '';

    // 头信息 array类型
    private  $headers;

    // post请求传递的参数 array类型
    private  $data;

    // 错误信息 string类型
    private  $errorMsg;

    // 返回对象 Object| array
    private $response;

    private $errorCode;

    public function __construct(string $url = null)
    {
        if (!extension_loaded('curl')) {
            throw new \ErrorException('cURL library is not loaded');
        }
        $this->curl = curl_init();

        if ($url != null) {
            $this->setUrl($url);
        }

    }

    /**
     * 设置URL
     *
     * @param string $url
     */
    public function setUrl(string $url, array $data = [])
    {
        $this->url = $url;
        if (!empty($data)) {
            $param_string = http_build_query($data);
            $this->url .= '?' . $param_string;
        }

        curl_setopt($this->curl, CURLOPT_URL, $this->url);
    }

    /**
     * 设置headers信息
     *
     * @param array $headers
     */
    public function setHeaders(array $headers)
    {
        $this->headers = $headers;
        curl_setopt($this->curl, CURLOPT_HEADER, $headers);
    }

    /**
     * 获取URL
     *
     * @return string
     */
    public function getUrl():string
    {
        return $this->url;
    }

    /**
     * 发起一个get方式请求
     *
     * @param string|null $url 目标网址
     * @param array $data 需要传递的参数，最终会被拼接到URL后面
     * @return mixed 返回一个response对象
     */
    public function get(string $url = null, array $data = [])
    {
        if (!$url) {
            $url = $this->getUrl();
        }
        $this->setUrl($url, $data);

        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); // 以文件流方式返回

        curl_setopt($this->curl, CURLOPT_HTTPGET, true);

        $this->exec();

        return $this->response;
    }

    public function post(string $url = null, string $postData, $json = false)
    {
        if (!$url) {
            $url = $this->getUrl();
        }
        $this->setUrl($url);
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_POST, 1);
        // 设置post数据
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postData);
        if ($json) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER,
                ['Content-Type: application/json; charset=utf-8', 'Content-Length:' . strlen($postData)]);
        }

        $this->exec();

        return $this->response;
    }

    public function delete(string $url = null, array $params = []):string
    {
        if (!$url) {
            $url = $this->getUrl();
        }

        if (!empty($params)) {
            $url .= '?' . http_build_query($params);
        }

        $this->setUrl($url);

        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
        $this->exec();
        return $this->response;
    }

    public function put(string $url, $putData):string
    {
        if (!$url) {
            $url = $this->getUrl();
        }

        $this->setUrl($url);

        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $putData);
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
        $this->exec();
        return $this->response;

    }

//    public function checkAndSetUrl(string $url) {
//        if (!$url) {
//            $url = $this->getUrl();
//        }
//        $this->setUrl($url, $data);
//    }

    /**
     * 执行函数，用于发起真正的请求。
     *
     * @param null $ch curl实例对象
     */
    public function exec($ch = null)
    {
        if ($ch != null) {
            $this->response = curl_exec($ch);
            $this->errorCode = curl_errno($ch);
            $this->errorMsg = curl_error($ch);

        } else {
            $this->response = curl_exec($this->curl);

            $this->errorCode = curl_errno($this->curl);

            $this->errorMsg = curl_error($this->curl);

        }
    }

}


